package com.vdong.data.service.impl;

import com.vdong.data.model.Template;
import com.vdong.data.model.TemplateCarryMode;
import com.vdong.data.model.enums.State;
import com.vdong.data.repository.TemplateCarryModeRespository;
import com.vdong.data.repository.TemplateRepository;
import com.vdong.data.service.TemplateService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.time.LocalDateTime;
import java.util.List;

@Service
public class TemplateServiceImpl implements TemplateService {

    private Logger logger = LoggerFactory.getLogger(TemplateServiceImpl.class);

    @PersistenceContext
    EntityManager entityManager;
    @Autowired
    private TemplateRepository templateRepository;

    @Autowired
    private TemplateCarryModeRespository templateCarryModeRespository;

    @Override
    public Template findById(String id, String key) {

        return templateRepository.findByIdAndUsersKey(id, key);

    }

    @Override
    @Transactional(rollbackFor = {Exception.class})

    public List<TemplateCarryMode> save(List<TemplateCarryMode> templateCarryMode) {

        return templateCarryModeRespository.save(templateCarryMode);

    }

    @Override
    public Page<Template> findByUserId(String userId, Pageable pagebale, String key) {
        return templateRepository.findByUserIdAndUsersKeyAndStateLessThanOrderByCreateTimeDesc(userId, key,
                State.DELETE, pagebale);

    }

    @Override
    public Template findByUserIdAndState(String userId, State state, String key) {

        return templateRepository.findByUserIdAndUsersKeyAndState(userId, key, state);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class}, isolation = Isolation.REPEATABLE_READ)
    public int updateStatusById(String id, String key) {
        Template template = this.findById(id, key);
        if (template != null && template.getState() == State.OFF) {
            template.setUpdateTime(LocalDateTime.now());
            template.setState(State.ON);
            templateRepository.updateStatusByUserIdAndState(1, template.getUserId(), template.getUsersKey(), 0);
            templateRepository.save(template);

            return 1;
        } else {
            return -1;
        }

    }

    @Override
    public TemplateCarryMode findByCitiesNameAndProvincesNameAndTemplateId(String citiesName, String provincesName,
                                                                           String userId, String key) {
        Template template = templateRepository.findByUserIdAndUsersKeyAndState(userId, key, State.ON);
        if (template == null)
            return null;
        String sql = "select id from template_carry_mode where template_id='" + template.getId()
                + "' and JSON_CONTAINS(areas->'$[*]', '{\"citiesName\":\"" + citiesName + "\", \"provincesName\":\""
                + provincesName + "\"}', '$')";
        Query query = entityManager.createNativeQuery(sql);
        List ls = query.getResultList();
        if (ls.size() == 0 || ls == null)
            return null;
        Integer id = Integer.parseInt(ls.get(0).toString());
        TemplateCarryMode templateCarryMode = templateCarryModeRespository.findOne(id);
        logger.info("findByCitiesNameAndProvincesNameAndTemplateId:citiesName" + citiesName + ":provincesName:"
                + provincesName + ":userId:" + userId + ":templateCarryModID:" + id);
        return templateCarryMode;
    }

    @Override
    public int deleteById(String id, String key) {
        Template template = this.findById(id, key);

        if (template != null && template.getState() == State.OFF) {
            template.setState(State.DELETE);
            templateRepository.save(template);
            logger.info("deleteTemplate:" + template.getUserId() + ":name:" + template.getName());
            return 1;

        }
        return 0;
    }

}
